package com.uzai.console.service.md.mdconfigplan.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.uzai.common.enums.RedisCacheKeyEnum;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.result.ResponseCode;
import com.uzai.console.common.UzaiRespVo;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.common.utils.DesensitizeUtil;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.constant.Const;
import com.uzai.console.dto.feign.turnlink.PddTokenRecordDto;
import com.uzai.console.dto.md.mdactivity.MdActivityQuery;
import com.uzai.console.dto.md.mdconfigplan.*;
import com.uzai.console.dto.pdd.pddtoken.PddTokenIdDto;
import com.uzai.console.entity.*;
import com.uzai.console.mapper.*;
import com.uzai.console.service.feign.UzaiTurnlinkFeignService;
import com.uzai.console.service.md.mdconfigplan.MdConfigPlanService;
import com.uzai.console.vo.md.mdconfigplan.MdConfigPlanVo;
import com.uzai.console.vo.pdd.pddtoken.PddTokenRecordVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 免单配置方案
 * @author liuqi
 * @date 2021年08月13日 11:34
 */
@Service
public class MdConfigPlanServiceImpl implements MdConfigPlanService {

    Logger logger = LoggerFactory.getLogger(MdConfigPlanServiceImpl.class);

    @Autowired
    private MdConfigPlanMapper mdConfigPlanMapper;
    @Autowired
    private MdActivityMapper mdActivityMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UzaiTurnlinkFeignService uzaiTurnlinkFeignService;
    @Autowired
    private PddTokenMapper pddTokenMapper;

    /**
     * 查询免单配置方案列表
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param mdConfigPlanQuery
     * @return null
     */
    public List<MdConfigPlanVo> findMdConfigPlanList(MdConfigPlanQuery mdConfigPlanQuery){
        //新建返回到页面的LIST对象
        List<MdConfigPlanVo> mdConfigPlanVoList = new ArrayList<>();

        //判断是否需要脱敏
        Boolean tuominFlag = true;
        String cmstype_amoy_gold_app_secret_verified =  (String)redisTemplate.opsForValue().get(String.format(Const.SmsType.CMSTYPE_AMOY_GOLD_APP_SECRET, mdConfigPlanQuery.getMerId()));
        if(StringUtils.isNotBlank(cmstype_amoy_gold_app_secret_verified)){
            tuominFlag = false;
        }

        //执行分页查询对象
        ArrayList<MdConfigPlan> mdConfigPlanList =  mdConfigPlanMapper.findByList(mdConfigPlanQuery);
        if(mdConfigPlanList != null && mdConfigPlanList.size() > 0){
            for (MdConfigPlan mdConfigPlan : mdConfigPlanList){
                MdConfigPlanVo mdConfigPlanVo = new MdConfigPlanVo();
                BeanUtils.copyProperties(mdConfigPlan, mdConfigPlanVo);

                //处理淘礼金脱敏显示
                //是否脱敏处理
                if(tuominFlag){
                    JSONObject jsonObject = JSONObject.parseObject(mdConfigPlanVo.getData());
                    if(jsonObject != null){
                        //淘礼金appSecret
                        String amoyGoldAppsecret = Tools.getStr(jsonObject.getString("amoyGoldAppsecret"));
                        //脱敏之后返回
                        jsonObject.put("amoyGoldAppsecret", DesensitizeUtil.around(amoyGoldAppsecret, 4, 4));
                        mdConfigPlanVo.setData(jsonObject.toJSONString());
                    }
                }

                mdConfigPlanVoList.add(mdConfigPlanVo);
            }
        }
        //返回到页面分页对象
        return mdConfigPlanVoList;
    }

    /**
     * 查询免单配置方案详情
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param mdConfigPlanIdDto
     * @return null
     */
    public MdConfigPlanVo findMdConfigPlan(MdConfigPlanIdDto mdConfigPlanIdDto){
        if(mdConfigPlanIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "id不能为空");
        }

        MdConfigPlan mdConfigPlan = mdConfigPlanMapper.selectById(mdConfigPlanIdDto.getId(), mdConfigPlanIdDto.getMerId());

        if(mdConfigPlan == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该免单配置不存在");
        }
        MdConfigPlanVo mdConfigPlanVo = new MdConfigPlanVo();
        BeanUtils.copyProperties(mdConfigPlan, mdConfigPlanVo);

        //处理淘礼金脱敏显示
        //是否脱敏处理
        String cmstype_amoy_gold_app_secret_verified =  (String)redisTemplate.opsForValue().get(String.format(Const.SmsType.CMSTYPE_AMOY_GOLD_APP_SECRET, mdConfigPlanIdDto.getMerId()));
        if(StringUtils.isBlank(cmstype_amoy_gold_app_secret_verified)){
            JSONObject jsonObject = JSONObject.parseObject(mdConfigPlanVo.getData());
            if(jsonObject != null){
                //淘礼金appSecret
                String amoyGoldAppsecret = Tools.getStr(jsonObject.getString("amoyGoldAppsecret"));
                //脱敏之后返回
                jsonObject.put("amoyGoldAppsecret", DesensitizeUtil.around(amoyGoldAppsecret, 4, 4));
                mdConfigPlanVo.setData(jsonObject.toJSONString());
            }
        }

        return mdConfigPlanVo;
    }

    /**
     * 添加免单配置方案
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param mdConfigPlanDto
     * @return null
     */
    @Transactional
    public MdConfigPlanVo addMdConfigPlan(MdConfigPlanDto mdConfigPlanDto){

        MdConfigPlanVo mdConfigPlanVo = new MdConfigPlanVo();

        int now = DateUtil.getNowTime();

        if(StringUtils.isBlank(mdConfigPlanDto.getName())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入名称");
        }

        //配置方案名称
        String name = Tools.getStr(mdConfigPlanDto.getName());
        if(StringUtils.isBlank(name)){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入配置方案名称");
        }

        //验证名称重复
        MdConfigPlan mdConfigPlan_name = mdConfigPlanMapper.selectByNameAndMerId(mdConfigPlanDto.getName(), mdConfigPlanDto.getMerId());
        if(mdConfigPlan_name != null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "名称重复");
        }

        MdConfigPlan mdConfigPlan = new MdConfigPlan();
        BeanUtils.copyProperties(mdConfigPlanDto, mdConfigPlan);
        mdConfigPlan.setId(IdWorker.getId());
        mdConfigPlan.setCreateTime(now);
        mdConfigPlan.setUpdateTime(now);
        BeanUtils.copyProperties(mdConfigPlan, mdConfigPlanVo);

        mdConfigPlanMapper.insertSelective(mdConfigPlan);

        //更新免单配置方案pid列表缓存
        List<String> pldList = new ArrayList<>();
        MdConfigPlanQuery mdConfigPlanQuery = new MdConfigPlanQuery();
        mdConfigPlanQuery.setMerId(mdConfigPlanDto.getMerId());
        List<MdConfigPlan> mdConfigPlanList = mdConfigPlanMapper.findByList(mdConfigPlanQuery);
        if(mdConfigPlanList != null && mdConfigPlanList.size() > 0){
            for (MdConfigPlan configPlan : mdConfigPlanList) {
                try {
                    JSONObject configPlan_data = JSONObject.parseObject(configPlan.getData());
                    String tbPid = configPlan_data.getString("tbPid");
                    pldList.add(tbPid);
                }catch (Exception e){

                }
            }
        }
        String data = Tools.getStrEmpty(JSONObject.toJSONString(pldList));
        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.MD_CONFIGPLAN_PID_LIST.getKey(), mdConfigPlanDto.getMerId()), data);

        return mdConfigPlanVo;
    }


    /**
     * 修改免单配置方案
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param mdConfigPlanDto
     * @return null
     */
    @Transactional
    public void updateMdConfigPlan(MdConfigPlanDto mdConfigPlanDto){

        int now = DateUtil.getNowTime();

        if(mdConfigPlanDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "id不能为空");
        }

        if(StringUtils.isBlank(mdConfigPlanDto.getName())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入免单配置方案名称");
        }

        MdConfigPlan mdConfigPlan = mdConfigPlanMapper.selectById(mdConfigPlanDto.getId(), mdConfigPlanDto.getMerId());

        if(mdConfigPlan == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该免单配置方案不存在");
        }

        //处理淘礼金脱敏处理
        //APP淘礼金appSecret
        String amoyGoldAppsecret_old = "";
        JSONObject jsonObject_old = JSONObject.parseObject(mdConfigPlan.getData());
        if(jsonObject_old != null){
            amoyGoldAppsecret_old = jsonObject_old.getString("amoyGoldAppsecret");
        }

        JSONObject jsonObject_new = JSONObject.parseObject(mdConfigPlanDto.getData());
        if(jsonObject_new != null){
            //APP淘礼金appSecret
            String amoyGoldAppsecret_new = Tools.getStr(jsonObject_new.getString("amoyGoldAppsecret"));
            //如果包含星星，则不修改
            if(amoyGoldAppsecret_new.contains("*")){
                jsonObject_new.put("amoyGoldAppsecret", amoyGoldAppsecret_old);
            }
            mdConfigPlanDto.setData(jsonObject_new.toJSONString());
        }


        //旧的淘宝联盟
        Long tbTokenId_old = null;
        JSONObject jsonObject_tb_old = JSONObject.parseObject(mdConfigPlan.getData());
        if (jsonObject_tb_old != null) {
            tbTokenId_old = Tools.getLong(jsonObject_tb_old.getLong("tbTokenId"));
        }

        //判断是否修改了淘宝联盟，只有未使用的配置方案才能修改淘宝联盟
        JSONObject jsonObject_tb_new = JSONObject.parseObject(mdConfigPlanDto.getData());
        if (jsonObject_tb_new == null) {
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "内容格式设置不正确");
        }

        Long tbTokenId_new = jsonObject_tb_new.getLong("tbTokenId");
        if(tbTokenId_new == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "未设置淘宝联盟");
        }

        //联盟不一样，则需要判断该配置方案是否已经使用，如果已经使用了，则不让修改淘宝联盟
        //联盟不一样，则需要判断该配置方案是否已经使用，如果已经使用了，则不让修改淘宝联盟
        if(tbTokenId_old != null){
            if(tbTokenId_new.longValue() != tbTokenId_old.longValue()){
                MdActivityQuery mdActivityQuery = new MdActivityQuery();
                mdActivityQuery.setMerId(mdConfigPlanDto.getMerId());
                mdActivityQuery.setMerId(mdConfigPlan.getId());
                List<MdActivity> mdActivityList = mdActivityMapper.findByList(mdActivityQuery);
                if(mdActivityList != null){
                    throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该配置方案已经被使用，不能修改淘宝联盟信息");
                }
            }
        }

        //验证新名字是否已经存在
        if(!mdConfigPlan.getName().equals(mdConfigPlanDto.getName())){ //表示修改了名称
            //验证新名称是否存在
            MdConfigPlan configPlan_name = mdConfigPlanMapper.selectByNameAndMerId(mdConfigPlanDto.getName(), mdConfigPlanDto.getMerId());
            if(configPlan_name != null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "名称重复");
            }
        }

        mdConfigPlan.setName(mdConfigPlanDto.getName());
        mdConfigPlan.setData(mdConfigPlanDto.getData());
        mdConfigPlan.setUpdateTime(now);
        mdConfigPlanMapper.updateById(mdConfigPlan);


        //更新免单配置方案pid列表缓存
        List<String> pldList = new ArrayList<>();
        MdConfigPlanQuery mdConfigPlanQuery = new MdConfigPlanQuery();
        mdConfigPlanQuery.setMerId(mdConfigPlanDto.getMerId());
        List<MdConfigPlan> mdConfigPlanList = mdConfigPlanMapper.findByList(mdConfigPlanQuery);
        if(mdConfigPlanList != null && mdConfigPlanList.size() > 0){
            for (MdConfigPlan configPlan : mdConfigPlanList) {
                try {
                    JSONObject configPlan_data = JSONObject.parseObject(configPlan.getData());
                    String tbPid = configPlan_data.getString("tbPid");
                    pldList.add(tbPid);
                }catch (Exception e){

                }
            }
        }
        String data = Tools.getStrEmpty(JSONObject.toJSONString(pldList));
        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.MD_CONFIGPLAN_PID_LIST.getKey(), mdConfigPlanDto.getMerId()), data);

    }

    /**
     * 删除
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param mdConfigPlanIdDto
     * @return null
     */
    @Transactional
    public void deleteMdConfigPlan(MdConfigPlanIdDto mdConfigPlanIdDto){
        if(mdConfigPlanIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "id不能为空");
        }

        MdConfigPlan mdConfigPlan = mdConfigPlanMapper.selectById(mdConfigPlanIdDto.getId(), mdConfigPlanIdDto.getMerId());
        if(mdConfigPlan == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该配置方案不存在");
        }

        mdConfigPlanMapper.deleteById(mdConfigPlanIdDto.getId(), mdConfigPlanIdDto.getMerId());

        //更新免单配置方案pid列表缓存
        List<String> pldList = new ArrayList<>();
        MdConfigPlanQuery mdConfigPlanQuery = new MdConfigPlanQuery();
        mdConfigPlanQuery.setMerId(mdConfigPlanIdDto.getMerId());
        List<MdConfigPlan> mdConfigPlanList = mdConfigPlanMapper.findByList(mdConfigPlanQuery);
        if(mdConfigPlanList != null && mdConfigPlanList.size() > 0){
            for (MdConfigPlan configPlan : mdConfigPlanList) {
                try {
                    JSONObject configPlan_data = JSONObject.parseObject(configPlan.getData());
                    String tbPid = configPlan_data.getString("tbPid");
                    pldList.add(tbPid);
                }catch (Exception e){

                }
            }
        }
        String data = Tools.getStrEmpty(JSONObject.toJSONString(pldList));
        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.MD_CONFIGPLAN_PID_LIST.getKey(), mdConfigPlanIdDto.getMerId()), data);

    }

    /**
     * 复制免单配置方案
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param mdConfigPlanCopyDto
     * @return null
     */
    @Transactional
    public MdConfigPlanVo copyMdConfigPlan(MdConfigPlanCopyDto mdConfigPlanCopyDto){

        int now = DateUtil.getNowTime();

        //判断ID是否未空
        if(mdConfigPlanCopyDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "id不能为空");
        }

        //判断配置方案名称是否未空
        if(StringUtils.isBlank(mdConfigPlanCopyDto.getName())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新配置方案名称不能为空");
        }

        //通过ID查询配置方案
        MdConfigPlan mdConfigPlan_old = mdConfigPlanMapper.selectById(mdConfigPlanCopyDto.getId(), mdConfigPlanCopyDto.getMerId());
        if(mdConfigPlan_old == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "当前的配置方案不存在");
        }

        //验证名称重复
        MdConfigPlan mdConfigPlan_name = mdConfigPlanMapper.selectByNameAndMerId(mdConfigPlanCopyDto.getName(), mdConfigPlanCopyDto.getMerId());
        if(mdConfigPlan_name != null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "名称重复");
        }

        //生成新的配置ID
        MdConfigPlan mdConfigPlan_new = new MdConfigPlan();
        BeanUtils.copyProperties(mdConfigPlan_old, mdConfigPlan_new);
        Long configPlanId_new = IdWorker.getId();
        mdConfigPlan_new.setId(configPlanId_new);
        mdConfigPlan_new.setName(mdConfigPlanCopyDto.getName());
        mdConfigPlan_new.setCreateTime(now);
        mdConfigPlan_new.setUpdateTime(now);
        mdConfigPlanMapper.insert(mdConfigPlan_new);

        //更新免单配置方案pid列表缓存
        List<String> pldList = new ArrayList<>();
        MdConfigPlanQuery mdConfigPlanQuery = new MdConfigPlanQuery();
        mdConfigPlanQuery.setMerId(mdConfigPlanCopyDto.getMerId());
        List<MdConfigPlan> mdConfigPlanList = mdConfigPlanMapper.findByList(mdConfigPlanQuery);
        if(mdConfigPlanList != null && mdConfigPlanList.size() > 0){
            for (MdConfigPlan configPlan : mdConfigPlanList) {
                try {
                    JSONObject configPlan_data = JSONObject.parseObject(configPlan.getData());
                    String tbPid = configPlan_data.getString("tbPid");
                    pldList.add(tbPid);
                }catch (Exception e){

                }
            }
        }
        String data = Tools.getStrEmpty(JSONObject.toJSONString(pldList));
        redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.MD_CONFIGPLAN_PID_LIST.getKey(), mdConfigPlanCopyDto.getMerId()), data);


        MdConfigPlanVo mdConfigPlanVo = new MdConfigPlanVo();
        BeanUtils.copyProperties(mdConfigPlan_new, mdConfigPlanVo);

        return mdConfigPlanVo;

    }

    /**
     * 修改免单配置方案名称
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param mdConfigPlanUpdateNameDto
     * @return null
     */
    @Transactional
    public Boolean updateMdConfigPlanName(MdConfigPlanUpdateNameDto mdConfigPlanUpdateNameDto){
        //判断ID是否未空
        if(mdConfigPlanUpdateNameDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "id不能为空");
        }

        //判断配置方案名称是否未空
        if(StringUtils.isBlank(mdConfigPlanUpdateNameDto.getName())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "新配置方案名称不能为空");
        }

        //通过ID查询配置方案
        MdConfigPlan mdConfigPlan = mdConfigPlanMapper.selectById(mdConfigPlanUpdateNameDto.getId(), mdConfigPlanUpdateNameDto.getMerId());
        if(mdConfigPlan == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "当前的配置方案不存在");
        }

        //验证新名字是否已经存在
        if(!mdConfigPlan.getName().equals(mdConfigPlanUpdateNameDto.getName())){ //表示修改了名称
            //验证新名称是否存在
            MdConfigPlan configPlan_name = mdConfigPlanMapper.selectByNameAndMerId(mdConfigPlanUpdateNameDto.getName(), mdConfigPlanUpdateNameDto.getMerId());
            if(configPlan_name != null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "名称重复");
            }
        }

        mdConfigPlan.setName(mdConfigPlanUpdateNameDto.getName());
        mdConfigPlan.setUpdateTime(DateUtil.getNowTime());

        mdConfigPlanMapper.updateById(mdConfigPlan);

        return true;
    }

    /**
     * 免单配置拼多多联盟备案
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param pddTokenIdDto
     * @return null
     */
    public PddTokenRecordVo recordPddToken(PddTokenIdDto pddTokenIdDto){
        if(pddTokenIdDto.getId() == null){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入拼多多联盟id");
        }

        //是否是多多进宝
        PddToken pddToken = pddTokenMapper.selectById(pddTokenIdDto.getId(), pddTokenIdDto.getMerId());
        if(pddToken == null){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该拼多多联盟不存在");
        }

        PddTokenRecordVo pddTokenRecordVo = new PddTokenRecordVo();
        //调用拼多多联盟备案接口
        PddTokenRecordDto pddTokenRecordDto = new PddTokenRecordDto();
        pddTokenRecordDto.setCustomParam("MD_" + pddTokenIdDto.getMerId());
        pddTokenRecordDto.setTokenId(pddTokenIdDto.getId());
        UzaiRespVo<String> uzaiRespVo = uzaiTurnlinkFeignService.pddCheckAuthority(pddTokenRecordDto);
        logger.info("--免单配置方案调用拼多多联盟备案接口--，para={},result={}", JSONObject.toJSONString(pddTokenRecordDto), JSONObject.toJSONString(uzaiRespVo));
        if(uzaiRespVo != null && uzaiRespVo.getCode() == 200 ){ //调用成功
            //如果返回data为空，则表示已经备案过
            if(StringUtils.isNotBlank(uzaiRespVo.getData())){
                pddTokenRecordVo.setRecordStatus(0); //未备案
                pddTokenRecordVo.setRecordUrl(uzaiRespVo.getData());
                //将免单备案链接保持到数据库当中
                if(pddToken != null){
                    pddToken.setMdRecordUrl(uzaiRespVo.getData());
                    pddTokenMapper.updateByIdSelective(pddToken);
                }
            }else{
                pddTokenRecordVo.setRecordStatus(1); //已经备案
            }
        }else{
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, uzaiRespVo == null || StringUtils.isBlank(uzaiRespVo.getMsg())? "请求备案失败!" : uzaiRespVo.getMsg());
        }
        return pddTokenRecordVo;
    }

}
